Android进阶八:RecyclerView自动滚动

您所在的位置:网站首页 安卓 自动滚屏幕 Android进阶八:RecyclerView自动滚动

Android进阶八:RecyclerView自动滚动

2023-08-13 10:47| 来源: 网络整理| 查看: 265

smoothScrollToPosition()

在使用RecyclerView的时候,有一些场景需要RecyclerView能自动滑动到指定的item,这种情况可以调用RecyclerView的以下方法来实现:

scrollToPosition(int position) smoothScrollToPosition(int position)

这两个方法传入需要滑动到的item的position就可以实现跳转到相应的item,区别是scrollToPosition()会立即跳转到相应item,不会有滑动的效果,smoothScrollToPosition()跳转的同时,会有滑动的效果,但是滑动速度很快,用户体验效果不好,如何能控制速度达到一个好的效果呢?

先来看下smoothScrollToPosition()的源码:

public void smoothScrollToPosition(int position) { if (mLayoutFrozen) { return; } if (mLayout == null) { Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. " + "Call setLayoutManager with a non-null argument."); return; } mLayout.smoothScrollToPosition(this, mState, position); }

它最终是调用了mLayout.smoothScrollToPosition(this, mState, position),mLayout是RecyclerView的布局管理器,比如线性布局管理器LinearLayoutManager:

mRecyclerView.setLayoutManager(mLinearLayoutManager);

来看下smoothScrollToPosition()在线性布局管理器中的实现:

@Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()); linearSmoothScroller.setTargetPosition(position); startSmoothScroll(linearSmoothScroller); }

使用的是LinearSmoothScroller进行滑动操作,再来看LinearSmoothScroller类,它有一个获取滑动速度的方法:

protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { return MILLISECONDS_PER_INCH / displayMetrics.densityDpi; }

所以我们可以想办法重写这个方法来改变RecyclerView滑动的速度。

我们自定义一个LinearLayoutManager:

public class ScrollLinearLayoutManager extends LinearLayoutManager { private static final float MILLISECONDS_PER_INCH = 25f; public ScrollLinearLayoutManager(Context context) { super(context); } @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, final int position) { LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) { @Nullable @Override public PointF computeScrollVectorForPosition(int targetPosition) { return ScrollLinearLayoutManager.this.computeScrollVectorForPosition(targetPosition); } @Override protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { return MILLISECONDS_PER_INCH / displayMetrics.densityDpi; } }; linearSmoothScroller.setTargetPosition(position); startSmoothScroll(linearSmoothScroller); } }

重写smoothScrollToPosition()方法,然后重新实例化一个LinearSmoothScroller,并重写calculateSpeedPerPixel()方法, 这样,可以调整MILLISECONDS_PER_INCH的值,来实现RecyclerView滑动速度的调整。

补充

由当前item到目标item的中间要滑动的item数量可能每次都不一样,这样固定的移动速度也会导致用户体验不好,所以可以根据需要滑动的item数量来动态的调整滑动速度, 我们再修改下calculateSpeedPerPixel():

protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { View view = getChildAt(0); if(view != null) { final int firstChildPos = getPosition(getChildAt(0)); //获取当前item的position int delta = Math.abs(position - firstChildPos);//算出需要滑动的item数量 if(delta == 0) delta = 1; return (MILLISECONDS_PER_INCH/delta) / displayMetrics.densityDpi; } else { return MILLISECONDS_PER_INCH / displayMetrics.densityDpi; } }

这样当需要滑动的item数量越多,滑动速度越快,item数量少时,滑动会较慢,这样就会有一个好的用户体验。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3